package com.davidhigenbottam.HeatMap.data;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.davidhigenbottam.HeatMap.shared.ColourBand;
import com.davidhigenbottam.HeatMap.shared.Institution;
import com.davidhigenbottam.HeatMap.shared.Province;
import com.davidhigenbottam.HeatMap.shared.Query;
import com.davidhigenbottam.HeatMap.shared.Result;

public abstract class ProvinceData extends Data {
	
	
	HashMap<String, Province> provinces = new HashMap<String, Province>();
	
	
	
	public static final int NUMBER_OF_BANDS=5;
	double[] colourBandBoundryValues= new double[NUMBER_OF_BANDS+1];
	
	
	public abstract String getDescription();
	
	public abstract void getProvincesFromDatabase();
	public abstract void getInstitutionsFromDatabase(Province p);
	
	

	
	public ProvinceData(Query q) {
		super(q);
		getProvincesFromDatabase();
		calculateColourBands();
	}
	
	
	public void getAllProvinces(Connection c) throws SQLException{
		// get all provinces
		PreparedStatement stmt = c.prepareStatement("select province.id, province.name, province.student_group_id as linkId "
				+ "from province " + "where province.country_id=?");
		stmt.setString(1, query.getCountryCode());
		if (stmt.execute()) {
			ResultSet rs = stmt.getResultSet();

			while (rs.next()) {
				Long provId = rs.getLong("id");
				
				String prov = rs.getString("name");
				provinces.put(prov, new Province(provId,prov));
			}
		}			
	}
	
	public void getTestProvinces(Query q) {

		provinces.put("Aceh", new Province("Aceh"));
		provinces.put("Sumatera Utara", new Province("Sumatera Utara"));
		provinces.put("Sumatera Barat", new Province("Sumatera Barat"));
		provinces.put("Riau", new Province("Riau"));
		provinces.put("Kepulauan Riau", new Province("Kepulauan Riau"));
		provinces.put("Jambi", new Province("Jambi"));
		provinces.put("Sumatera Selatan", new Province("Sumatera Selatan"));
		provinces.put("Kep Bangka Belitung",
				new Province("Kep Bangka Belitung"));
		provinces.put("Bengkulu", new Province("Bengkulu"));
		provinces.put("Lampung", new Province("Lampung"));
		provinces.put("DKI Jakarta", new Province("DKI Jakarta"));
		provinces.put("Jawa Barat", new Province("Jawa Barat"));
		provinces.put("Banten", new Province("Banten"));
		provinces.put("Jawa Tengah", new Province("Jawa Tengah"));
		provinces.put("Dista Yogyakarta", new Province("Dista Yogyakarta"));
		provinces.put("Jawa Timur", new Province("Jawa Timur"));
		provinces.put("Bali", new Province("Bali"));
		provinces.put("Nusa Tenggara Barat",
				new Province("Nusa Tenggara Barat"));
		provinces.put("Nusa Tenggara Timur",
				new Province("Nusa Tenggara Timur"));
		provinces.put("Kalimantan Barat", new Province("Kalimantan Barat"));
		provinces.put("Kalimantan Tengah", new Province("Kalimantan Tengah"));
		provinces.put("Kalimantan Selatan", new Province("Kalimantan Selatan"));
		provinces.put("Kalimantan Timur", new Province("Kalimantan Timur"));
		provinces.put("Sulawesi Utara", new Province("Sulawesi Utara"));
		provinces.put("Gorontalo", new Province("Gorontalo"));
		provinces.put("Sulawesi Tengah", new Province("Sulawesi Tengah"));
		provinces.put("Sulawesi Selatan", new Province("Sulawesi Selatan"));
		provinces.put("Sulawesi Barat", new Province("Sulawesi Barat"));
		provinces.put("Sulawesi Tenggara", new Province("Sulawesi Tenggara"));
		provinces.put("Maluku", new Province("Maluku"));
		provinces.put("Maluku Utara", new Province("Maluku Utara"));
		provinces.put("Papua", new Province("Papua"));
		provinces.put("Papua Barat", new Province("Papua Barat"));

		
		for (Province p : provinces.values()) {
			p.setVal((double) (Math.random() * 100d));
			//p.setVal(23.4553485d);
		}

	}

	void calculateColourBands() {
		// get min and max values
		double min = 0f, max = 0f;
		boolean notSet = true;

		//log.info("find min and max");

		for (Province p : provinces.values()) {
			if (p.hasValue()) {
				if (notSet) {
					min = p.getVal();
					max = p.getVal();
					notSet = false;
				}
				if (p.getVal() < min)
					min = p.getVal();
				if (p.getVal() > max)
					max = p.getVal();
			}
		}

		//log.info("min:" + min + " max:" + max);
		

		double spread = max - min;

		double bucketSize = spread / 5d;
		
		colourBandBoundryValues[0]= min;
		for(int i= 0; i<NUMBER_OF_BANDS+1;i++){
			colourBandBoundryValues[i]= min + bucketSize*((double)i);
		}
		
		//log.info("spread:" + spread + " bucketSize:" + bucketSize);

		for (Province p : provinces.values()) {
			if(p.hasValue()){
				int band = (int) ((p.getVal() - min) / bucketSize);
	
				// the max val will produce band 5 which should be 4
				// fix that
				if (band == 5)
					band = 4;
	
				// log.info("val:"+p.getVal()+ " band:"+band);
				ColourBand cb = ColourBand.values()[band];
				//log.info("cb:" + cb);
				p.setColourBand(cb);
			}
			else{
				p.setColourBand(ColourBand.NODATA);
			}
		}

	}

	public double[] getColourBandBoundryValues(){
		return colourBandBoundryValues;
	}
	
	
	public Province[] getAll(){
		return provinces.values().toArray(new Province[0]);	
	}
	
	
	public List<Province> getList() {
		List<Province> list = new ArrayList<Province>(provinces.values());
		return list;
	}
	public List<Result> getResultsList() {
		List<Result> list = new ArrayList<Result>(provinces.values());
		return list;
	}	
	
	
	public List<Institution> getInstitutionList(Province p){
		//lazy initialization
		if(p.getInstitutions()==null)
			getInstitutionsFromDatabase(p);
		return p.getInstitutions();
	}
	
	public Province getProvince(String name) {
		return provinces.get(name);

	}
	
}
